package org.fujene.memoryblock.repli;

import java.io.IOException;

import org.fujene.memoryblock.MemoryBlock;
import org.fujene.structure.Constants;
import org.fujene.structure.InvertIndexData;
import org.fujene.structure.LookupPointer;
import org.fujene.toolbox.ByteConverter;

public class ReplicateInvertIndexBlock extends MemoryBlock {
	private int opt_length = 0;

	public ReplicateInvertIndexBlock(int bodySize, int ID, boolean isAllocate) {
		super(bodySize, ID, Constants.MEMORY_TYPE_INVINDEX, isAllocate);
	}

	public InvertIndexData getInvertIndex(int ptr) {
		if (ptr > this.bodySize - (PTR + 4 + TERMFREQ)) {
			return null;
		}
		LookupPointer prevPtr = ByteConverter.getPtr(getBody(ptr, PTR));
		if (prevPtr.equals(Constants.emptyPointer))
			prevPtr = null;

		ptr += PTR;
		long diffID = ByteConverter.byteToLong(getBody(ptr, 4));

		ptr += 4;
		int termfreq = ByteConverter.byteToInt(getBody(ptr, TERMFREQ));

		return new InvertIndexData(prevPtr, diffID, termfreq);
	}

	// 末尾に追加するのみ 相対ポインタ対応
	public LookupPointer setInvertIndex(LookupPointer prevPtr, long diffID, int termfreq) {
		if (bodyVacancy < (PTR + 4 + TERMFREQ))
			return null;

		int ptr = bodySize - bodyVacancy;

		bodyVacancy -= (PTR + 4 + TERMFREQ);
		opt_length++;

		if (prevPtr == null) {
			prevPtr = Constants.emptyPointer;
		}
		setBody(ByteConverter.setPtr(prevPtr), ptr);
		ptr += PTR;
		setBody(ByteConverter.longToByte(diffID, 4), ptr);
		ptr += 4;
		setBody(ByteConverter.intToByte(termfreq, 4), ptr);
		ptr -= 4 + PTR;

		return new LookupPointer(this.getID(), ptr);
	}

	public int getLeft() {
		return bodyVacancy / (PTR + 4 + TERMFREQ);
	}

	@Override
	public int getOptionSize() {
		return 1;
	}

	@Override
	public byte[] getOptionByteStream() {
		return ByteConverter.intToByte(opt_length, 4);
	}

	@Override
	public void setOption(int option, int value) {
		if (option == 0)
			opt_length = value;
	}

	@Override
	public String getClassName() {
		return new String("ExtendInvertIndexBlock");
	}
	
	@Override
	public byte[] getData() throws IOException {
		throw new NoSuchMethodError("Unimplemented method");
	}

	@Override
	public void setData(byte[] array) throws IOException {
		throw new NoSuchMethodError("Unimplemented method");
	}
}
